package com.ogawa.joypal.distributionnetwork.activity

import android.annotation.SuppressLint
import android.content.Intent
import android.net.wifi.ScanResult
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.alibaba.android.arouter.facade.annotation.Route
import com.blankj.utilcode.util.LogUtils
import com.easepal.softaplib.BioClient
import com.easepal.softaplib.IConnectListener
import com.easepal.softaplib.wifi.OnWifiConnectListener
import com.easepal.softaplib.wifi.WiFiManager
import com.ogawa.base.base.BaseActivity
import com.ogawa.base.bean.LoadState
import com.ogawa.projectcommon.constants.UrlPathConstant
import com.ogawa.base.utils.HexUtil
import com.ogawa.joypal.distributionnetwork.Constants.AT_GET_MAC
import com.ogawa.joypal.distributionnetwork.R
import com.ogawa.joypal.distributionnetwork.viewmodel.GetSnViewModel
import com.ogawa.joypal.distributionnetwork.widget.ArcSeekBar
import com.ogawa.projectcommon.utils.ProjectSpUtils
import kotlinx.android.synthetic.main.activity_net_connect.*
import java.lang.ref.WeakReference


@Route(path = UrlPathConstant.ACTIVITY_DISTRIBUTIONNETWORK_NET_CONNECT)
class NetConnectActivity : BaseActivity(), View.OnClickListener {
    private lateinit var animation: Animation
    private var scanResult: ScanResult? = null
    private var psw: String? = null
    private var isApSuccess = false
    private var isConnectingSocket = false
    private var deviceMac: String? = null
    private var bioClient: BioClient? = null
    private var socketRetryCount = 2//socket重连次数
    private var wifiRetryCount = 5//Wifi重连次数
    private var isConnectingApWifi: Boolean = false//是否正在连接椅子wifi
    private var isConnectingWifi: Boolean = false//是否正在连接可用wifi
    private var getSnFail = false
    private lateinit var snViewModel: GetSnViewModel

    companion object {
        const val AUTO_LINK_SSID = "OGAWATECH-WIFI"
        const val DEVICE_AP_IP = "10.10.100.1"
        const val DEVICE_AP_PORT = 5000

        const val AP_WIFI_CONNECT_FAIL = 1
        const val CONNECT_SOCKET_FAIL = 2
        const val USEFUL_WIFI_CONNECT_FAIL = 3
        const val GET_SN_TIMEOUT = 4
        const val AP_WIFI_CONNECT_SUCCESS = 5
        const val GET_MAC_SUCCESS = 6
        const val GET_SN_SUCCESS = 7
        const val SN_TIMEOUT_TIME = 60000L // 读取Sn码超时时长
        const val CONNECT_SOCKET_TIMEOUT_TIME = 30*1000L//socket连接超时时长
    }

    private val _mHandler = MyHandler(this)

    internal class MyHandler(activity: NetConnectActivity?) : Handler() {
        private var weakReference= WeakReference(activity)
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                AP_WIFI_CONNECT_FAIL -> weakReference.get()?.onStepFail(weakReference.get()?.iv_state_1)
                CONNECT_SOCKET_FAIL -> weakReference.get()?.onStepFail(weakReference.get()?.iv_state_2)
                USEFUL_WIFI_CONNECT_FAIL -> weakReference.get()?.onStepFail(weakReference.get()?.iv_state_3)
                GET_SN_TIMEOUT -> {
                    weakReference.get()?.onStepFail(weakReference.get()?.iv_state_3)
                    weakReference.get()?.getSnFail = true
                }
                AP_WIFI_CONNECT_SUCCESS -> {
                    weakReference.get()?.isConnectingApWifi = false
                    weakReference.get()?.onStepSuccess(weakReference.get()?.iv_state_1)
                }
                GET_MAC_SUCCESS -> weakReference.get()?.onStepSuccess(weakReference.get()?.iv_state_2)
                GET_SN_SUCCESS -> weakReference.get()?.onStepSuccess(weakReference.get()?.iv_state_3)
            }
        }

    }


    private val connectListener = object : IConnectListener {
        override fun onMessage(bytes: ByteArray?) {
            if (bytes != null) {
                parseMessage(bytes)
            }
        }

        override fun onConnectionFailed() {
            LogUtils.e("连接椅子AP 失败 onConnectionFailed:${isConnectingSocket}")
            if (isConnectingSocket) {
                if (socketRetryCount > 0) {
                    socketRetryCount--
                    bioClient?.reconnect()
                } else {
                    _mHandler.removeMessages(CONNECT_SOCKET_FAIL)
                    _mHandler.sendEmptyMessage(CONNECT_SOCKET_FAIL)
                }
            }
        }

        override fun onConnectionSuccess() {
            LogUtils.e("onConnectionSuccess")
            if (isConnectingSocket) {
                _mHandler.removeMessages(CONNECT_SOCKET_FAIL)
                isConnectingSocket = false
                setDeviceNetWork()
            }
        }
    }

    override fun getLayoutId(): Int {
        return R.layout.activity_net_connect
    }

    override fun initView() {
        super.initView()
        setTitle(getString(R.string.connect_wifi))
        WiFiManager.getInstance(this).registerBroadcastReceivers(this)
        initWifiConnectListener()
        tv_watch_reason_1.setOnClickListener(this)
        tv_watch_reason_2.setOnClickListener(this)
        tv_watch_reason_3.setOnClickListener(this)
        tv_hand_connect.setOnClickListener(this)
        tv_result.setOnClickListener(this)
        initAnimation()
        initProgressListener()
        scanResult = intent.getParcelableExtra("scanResult")
        psw = intent.getStringExtra("psw")
        val currentSSID =
            WiFiManager.getInstance(this).connectionInfo.ssid.replace("\"".toRegex(), "")
        LogUtils.e("currentSSID:$currentSSID")
        if (AUTO_LINK_SSID == currentSSID) {
            _mHandler.sendEmptyMessage(AP_WIFI_CONNECT_SUCCESS)
        } else {
            WiFiManager.getInstance(this).connectOpenNetwork(AUTO_LINK_SSID)
            isConnectingApWifi = true
        }
        initViewModel()
    }

    private fun initViewModel() {
        snViewModel = ViewModelProviders.of(this).get(GetSnViewModel::class.java)
        snViewModel.let {  }
        snViewModel.loadState.observe(this, Observer {
            when (it) {
                is LoadState.Loading -> {
                    LogUtils.e("LoadState.Loading")
                }
                is LoadState.Fail -> {
                    LogUtils.e("LoadState.Fail:${it.msg}")
                    if (!getSnFail) {
                        _mHandler.postDelayed({ getSn() }, 2000)
                    }
                }
                is LoadState.Success -> {

                }
            }
        })
        snViewModel.deviceBean.observe(this, Observer {deviceBean->
            LogUtils.e("deviceBean  获取数据成功:${deviceBean.sn}")
            _mHandler.removeMessages(GET_SN_TIMEOUT)
            ProjectSpUtils.setProjectConfigWifiDeviceBean(
                ProjectSpUtils.getProjectConfigWifiDeviceBean().also { it.deviceSN = deviceBean.sn }
            )
            _mHandler.sendEmptyMessage(GET_SN_SUCCESS)
        })
    }

    private fun initWifiConnectListener() {
        WiFiManager.getInstance(this).setOnWifiConnectListener(object : OnWifiConnectListener {
            override fun onWiFiConnectSuccess(SSID: String?) {
                if (SSID != null && !SSID.contains("unknown ssid")) {
                    val ssid = SSID.replace("\"".toRegex(), "")
                    if (!isApSuccess && isConnectingApWifi) {//连接设备热点
                        if (ssid == AUTO_LINK_SSID) {
                            isApSuccess = true
                            _mHandler.postDelayed(
                                { _mHandler.sendEmptyMessage(AP_WIFI_CONNECT_SUCCESS) },
                                1000
                            )
                        } else {
                            if (wifiRetryCount > 0) {
                                wifiRetryCount--
                                WiFiManager.getInstance(this@NetConnectActivity)
                                    .connectOpenNetwork(AUTO_LINK_SSID)
                            } else {
                                _mHandler.sendEmptyMessage(AP_WIFI_CONNECT_FAIL)
                            }
                        }
                    }
                    if (isApSuccess && isConnectingWifi) {//连接可用热点
                        if (scanResult != null && ssid == scanResult!!.SSID) {//连接可用网络成功
                            isConnectingWifi = false
                            getSn()
                            _mHandler.sendEmptyMessageDelayed(
                                GET_SN_TIMEOUT,
                                SN_TIMEOUT_TIME
                            )
                        } else {
                            if (wifiRetryCount > 0) {
                                wifiRetryCount--
                                WiFiManager.getInstance(this@NetConnectActivity)
                                    .connectAp(scanResult, psw)
                            } else {
                                _mHandler.sendEmptyMessage(USEFUL_WIFI_CONNECT_FAIL)
                            }
                        }
                    }
                }
            }

            override fun onWiFiPreConnect(isFinished: Boolean) {
                LogUtils.e("onWiFiPreConnect:$isFinished")

            }

            override fun onWiFiConnectFailure(SSID: String?) {
                LogUtils.e("onWiFiConnectFailure:$SSID")
            }

        })
    }

    private fun initProgressListener() {
        asb_progress.setOnProgressChangeListener(object : ArcSeekBar.OnProgressChangeListener {
            @SuppressLint("SetTextI18n")
            override fun onProgressChanged(seekBar: ArcSeekBar?, progress: Int, isUser: Boolean) {
                tv_progress.text = "$progress%"
            }

            override fun onStartTrackingTouch(seekBar: ArcSeekBar?) {

            }

            override fun onStopTrackingTouch(seekBar: ArcSeekBar?) {

            }

        })
    }

    private fun initAnimation() {
        animation = AnimationUtils.loadAnimation(this, R.anim.anim_rotate)
        animation.repeatCount = Animation.INFINITE
        animation.interpolator = LinearInterpolator()
        iv_state_1.animation = animation
        iv_state_2.animation = animation
        iv_state_3.animation = animation
        iv_state_1.animation.start()
    }

    private fun onStepSuccess(ivState: ImageView?) {
        when (ivState?.id) {
            R.id.iv_state_1 -> {
                if (iv_state_1.animation != null) {
                    iv_state_1.animation.cancel()
                    iv_state_1.animation = null
                }
                tv_progress_1.text = getString(R.string.progress_1_success)
                iv_state_1.setImageResource(R.drawable.img_complete)
                asb_progress.progress = 33
                group_progress_2.visibility = View.VISIBLE
                if (iv_state_2.animation == null) {
                    iv_state_2.animation = animation
                }
                iv_state_2.animation.start()
                _mHandler.postDelayed({ connectSocket() }, 1000)
            }
            R.id.iv_state_2 -> {
                if (iv_state_2.animation != null) {
                    iv_state_2.animation.cancel()
                    iv_state_2.animation = null
                }
                tv_progress_2.text = getString(R.string.progress_2_success)
                iv_state_2.setImageResource(R.drawable.img_complete)
                asb_progress.progress = 66
                group_progress_3.visibility = View.VISIBLE
                if (iv_state_3.animation == null) {
                    iv_state_3.animation = animation
                }
                iv_state_3.animation.start()
            }
            R.id.iv_state_3 -> {
                if (iv_state_3.animation != null) {
                    iv_state_3.animation.cancel()
                    iv_state_3.animation = null
                }
                tv_progress_3.text = getString(R.string.progress_3_success)
                iv_state_3.setImageResource(R.drawable.img_complete)
                asb_progress.progress = 100
            }
        }
    }

    private fun onStepFail(ivState: ImageView?) {
//        if (MainActivity.failTimes < 3) {
//            MainActivity.failTimes++
//        } else {
//            tv_hand_connect.visibility = View.VISIBLE
//        }
        tv_reason.text = getString(R.string.net_config_fail_tip)
        group_progress.visibility = View.GONE
        iv_fail_tip.visibility = View.VISIBLE
        tv_result.text = getString(R.string.retry)
        when (ivState?.id) {
            R.id.iv_state_1 -> {
                if (iv_state_1.animation != null) {
                    iv_state_1.animation.cancel()
                    iv_state_1.animation = null
                }
                iv_state_1.setImageResource(R.drawable.img_fail)
                tv_watch_reason_1.visibility = View.VISIBLE
                tv_progress_1.text = getString(R.string.progress_1_fail)
            }
            R.id.iv_state_2 -> {
                if (iv_state_2.animation != null) {
                    iv_state_2.animation.cancel()
                    iv_state_2.animation = null
                }
                iv_state_2.setImageResource(R.drawable.img_fail)
                tv_watch_reason_2.visibility = View.VISIBLE
                tv_progress_2.text = getString(R.string.progress_2_fail)
            }
            R.id.iv_state_3 -> {
                if (iv_state_3.animation != null) {
                    iv_state_3.animation.cancel()
                    iv_state_3.animation = null
                }
                iv_state_3.setImageResource(R.drawable.img_fail)
                tv_watch_reason_3.visibility = View.VISIBLE
                tv_progress_3.text = getString(R.string.progress_3_fail)
            }
        }
    }

    private fun getSn() {
        if (TextUtils.isEmpty(deviceMac) || getSnFail) {
            return
        }
        LogUtils.e("getSn")
        snViewModel.getSn(deviceMac!!)
    }

    private fun connectSocket() {
        closeSocket()
        newSocket()
        if (bioClient != null && !isConnectingSocket) {
            deviceMac = null
            isConnectingSocket = true
            bioClient!!.connect()
            socketRetryCount = 2
            _mHandler.sendEmptyMessageDelayed(
                CONNECT_SOCKET_FAIL,
                CONNECT_SOCKET_TIMEOUT_TIME
            )
        }
    }

    /**
     * 关闭Socket连接
     */
    private fun closeSocket() {
        if (bioClient != null) {
            bioClient!!.disconnect()
            bioClient = null
        }
    }

    /**
     * 新建Socket客户端对象
     */
    private fun newSocket() {
        if (bioClient == null) {
            bioClient = BioClient(connectListener)
            bioClient!!.setConnectAddress(
                DEVICE_AP_IP,
                DEVICE_AP_PORT
            )
        }
    }

    /**
     * 发送WIFI账号密码至设备
     * ','使用'\,'表示，'$'使用'\$'表示，'\'使用'\\'表示。AT指令中作为参数分隔符的','、'$'不进行转义
     */
    fun setDeviceNetWork() {
        var wifiName = scanResult?.SSID
        wifiName = wifiName?.replace("\\", "\\\\")
        wifiName = wifiName?.replace(",", "\\,")
        wifiName = wifiName?.replace("$", "\\$")

        var psw = this.psw
        psw = psw?.replace("\\", "\\\\")
        psw = psw?.replace(",", "\\,")
        psw = psw?.replace("$", "\\$")
        val msg = "AT+SETWLAN=$wifiName,$psw$"
        bioClient?.sendMsg(msg)
    }

    /**
     * 解析设备发来的信息
     * @param bytes 字节数组
     */
    private fun parseMessage(bytes: ByteArray) {
        val s = String(bytes)
        LogUtils.e("解析设备发来的信息:$s")
        if (s.contains("OK")) {
            if (deviceMac.isNullOrBlank()) {
                getDeviceMac()
            } else {
                connectRouter()
            }
        } else {
            val mac = HexUtil.getHexString(bytes, 0, bytes.size, false)
            if (null != mac && mac.length == 12) {
                deviceMac = mac.toUpperCase()
                _mHandler.sendEmptyMessage(GET_MAC_SUCCESS)
                connectRouter()
            }
        }
    }

    /**
     * 获取设备MAC地址
     */
    private fun getDeviceMac() {
        val msg = AT_GET_MAC
        bioClient?.sendMsg(msg)
    }

    /**
     * 连接路由器（可联网的WIFI）
     */
    private fun connectRouter() {
        closeSocket()
        isConnectingWifi = true
        wifiRetryCount = 5
        WiFiManager.getInstance(this).connectAp(scanResult, psw)
    }


    override fun onDestroy() {
        super.onDestroy()
        _mHandler.removeCallbacksAndMessages(null)
        WiFiManager.getInstance(this).onDestroy(this)
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.tv_watch_reason_1, R.id.tv_watch_reason_2, R.id.tv_watch_reason_3 -> {
                startActivity(Intent(this, ReasonActivity::class.java))
                finish()
            }
            R.id.tv_hand_connect -> {
                startActivity(Intent(this, HandConnectActivity::class.java))
                finish()
            }
            R.id.tv_result -> {
                if (tv_result.text.toString() == getString(R.string.start_use)) {
                    if (asb_progress.progress == 100) {
                        SelectRoomActivity.startSelectRoomActivity(mActivity)
//                        ARouter.getInstance().build(UrlPathConstant.ACTIVITY_3209E_DEVICE_MAIN).navigation()
//                        finish()
                    }
                } else {
                    startActivity(Intent(this,StartNetActivity::class.java))
                    finish()
                }
            }
        }
    }
}